package com.k2data.k2app;
/**
 * Created by clb on 17-4-5.
 */

import com.alibaba.fastjson.JSONObject;
import com.k2data.k2app.common.K2Assert;
import com.k2data.k2app.common.MyConstant;
import com.k2data.k2app.util.PasHttpUtil;
import com.k2data.k2app.util.cas.CasHttpClient;
import lombok.extern.log4j.Log4j2;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.beans.factory.annotation.Autowired;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;

@Log4j2
public class HttpClientUtil {
    private static MyConstant myConstant;

    @Autowired
    public HttpClientUtil(MyConstant myConstant) {
        HttpClientUtil.myConstant = myConstant;
    }
    public static  HttpClient httpClient;
    static {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            LayeredConnectionSocketFactory layeredConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
                    new HostnameVerifier() {
                        @Override
                        public boolean verify(String hostname, SSLSession session) {
                            return true;
                        }
                    });

            RequestConfig.Builder requestBuilder = RequestConfig
                    .custom()
                    .setConnectTimeout(10000)
                    .setConnectionRequestTimeout(10000)
                    .setSocketTimeout(10000);

            httpClient = HttpClients
                    .custom()
                    .setDefaultRequestConfig(requestBuilder.build())
                    .setSSLSocketFactory(layeredConnectionSocketFactory)
                    .build();
        } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
            log.debug("httpclient init failed! message:{}",e.getMessage());
        }
    }

    public static String onGet(String uri) throws Exception{
        log.debug(String.format("GET url:%s",uri));
        HttpGet httpGet = new HttpGet(uri);
        BufferedReader reader = null;
        HttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(httpGet);
            reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "utf-8"));
            return reader.readLine();
        } catch (Exception e){
            K2Assert.connectionException(e);
        }finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    public static String onPost(String uri,Map<String,String> params)  throws Exception{
        log.debug(String.format("POST : url:%s",uri));
        HttpPost httpRequst = new HttpPost(uri);
        httpRequst.addHeader("Content-type","application/json; charset=utf-8");
        httpRequst.setHeader("Accept", "application/json");
        HttpResponse httpResponse = null;
        try {
            JSONObject jsonParam = new JSONObject();
            if(params != null){
                params.forEach((k,v) -> {
                    jsonParam.put(k, v);
                });
            }
            //解决中文乱码问题
            StringEntity entity = new StringEntity(jsonParam.toString(),"utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpRequst.setEntity(entity);
//            httpResponse = httpClient.execute(httpRequst);
//            CasHttpClient casHttpClient = new CasHttpClient("https://192.168.130.62:8443/cas");
            CasHttpClient casHttpClient = getHttpClient();
            httpResponse = casHttpClient.doPost(httpRequst);
            return doExecute(httpResponse);
        }catch (Exception  e){
            K2Assert.connectionException(e);
        }
        return null;
    }

    public static String onPostObject(String uri,Object params)  throws Exception{
        log.debug(String.format("POST : url:%s",uri));
        HttpPost httpRequst = new HttpPost(uri);
        httpRequst.addHeader("Content-type","application/json; charset=utf-8");
        httpRequst.setHeader("Accept", "application/json");
        HttpResponse httpResponse = null;
        try {
            String jsonParam = JSONObject.toJSONString(params);
            //解决中文乱码问题
            StringEntity entity = new StringEntity(jsonParam,"utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpRequst.setEntity(entity);
//            httpResponse = httpClient.execute(httpRequst);
//            CasHttpClient casHttpClient = new CasHttpClient("https://192.168.130.62:8443/cas");
            CasHttpClient casHttpClient = getHttpClient();
            httpResponse = casHttpClient.doPost(httpRequst);
            return doExecute(httpResponse);
        }catch (Exception  e){
            K2Assert.connectionException(e);
        }
        return null;
    }

    public static String onPutObject(String uri,Object params)  throws Exception{
        log.debug(String.format("PUT : url:%s",uri));
        HttpPut httpRequst = new HttpPut(uri);
        httpRequst.addHeader("Content-type","application/json; charset=utf-8");
        httpRequst.setHeader("Accept", "application/json");
        HttpResponse httpResponse = null;
        try {
            String jsonParam = JSONObject.toJSONString(params);
            StringEntity entity = new StringEntity(jsonParam,"utf-8");//解决中文乱码问题
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            httpRequst.setEntity(entity);
//            httpResponse = httpClient.execute(httpRequst);
//            CasHttpClient casHttpClient = new CasHttpClient("https://192.168.130.62:8443/cas");
            CasHttpClient casHttpClient = getHttpClient();
            httpResponse = casHttpClient.doPut(httpRequst);
            return doExecute(httpResponse);
        }catch (Exception  e){
            K2Assert.connectionException(e);
        }
        return null;
    }

    public static String onDelete(String uri) throws Exception {
        log.debug(String.format("DELETE : url:%s",uri));
        HttpDelete httpDelete = new HttpDelete(uri);
        httpDelete.addHeader("Content-type","application/json; charset=utf-8");
        httpDelete.setHeader("Accept", "application/json");
        HttpResponse httpResponse = null;
        try {
//             httpResponse = httpClient.execute(httpDelete);
            CasHttpClient casHttpClient = getHttpClient();
            httpResponse = casHttpClient.doDelete(httpDelete);
            return doExecute(httpResponse);
        }catch (Exception  e){
            K2Assert.connectionException(e);
        }
        return null;
    }

    public static String doExecute(HttpResponse httpResponse) throws Exception{
        BufferedReader reader = null;
        String result = "";
        try {
            reader = new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(), "utf-8"));
            result = reader.readLine();
        } catch (Exception e) {
            K2Assert.connectionException(e);
            result = e.getMessage().toString();
        }finally {
            if (reader != null) {
                reader.close();
            }
        }
        return result;
    }
    public static CasHttpClient getHttpClient () throws Exception {
        CasHttpClient casHttpClient = new CasHttpClient(myConstant.getTokenService(),myConstant.getTokenValue(),myConstant.proLoginUrl());
        return casHttpClient;
    }
}